home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / map_continents.pro < prev    next >
Text File  |  1997-07-08  |  11KB  |  316 lines

  1. ; $Id: map_continents.pro,v 1.19 1997/03/26 00:15:35 dave Exp $
  2. ;
  3. ; Copyright (c) 1993-1997, Research Systems, Inc.  All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5.  
  6. ;+
  7. ; NAME:
  8. ;       MAP_CONTINENTS
  9. ;
  10. ; PURPOSE:
  11. ;       The MAP_CONTINENTS procedure draws continental boundaries,
  12. ; filled continents, political boundaries, coastlines, and/or rivers,
  13. ; over an existing map projection established by MAP_SET. Outlines can
  14. ; be drawn in low or high-resolution (if the optional high-resolution
  15. ; CIA World Map database is installed). If MAP_CONTINENTS is called
  16. ; without any keywords, it draws low-resolution, unfilled continent
  17. ; outlines.
  18. ;
  19. ; MAP_SET must be called before MAP_CONTINENTS to establish the
  20. ; projection type, the center of the projection, polar rotation
  21. ; and geographic limits.
  22. ;
  23. ; Keywords not recognized are passed along in _EXTRA to PLOTS and/or
  24. ; POLYFILL depending on options requested.
  25. ;
  26. ; CATEGORY:
  27. ;              MAPPING
  28. ;
  29. ; CALLING SEQUENCE:
  30. ;              MAP_CONTINENTS
  31. ;
  32. ; INPUTS:
  33. ;              NONE
  34. ;
  35. ; INPUT KEYWORD PARAMETERS:
  36. ; COASTS -- Set this keyword to draw coastlines, islands, and lakes instead of
  37. ;           the default continent outlines. Note that if you are using the
  38. ;           low-resolution map database (if the HIRES keyword is not set), many
  39. ;           islands are drawn even when COASTS is not set. If you are using the 
  40. ;           hi gh-resolution map database (if the HIRES keyword is set),
  41. ;           no islands are drawn unless COASTS is set.
  42. ; COLOR -- The color index of the lines being drawn.
  43. ; COUNTRIES -- Set this keyword to draw political boundaries as of 1993.
  44. ; _EXTRA -- Other keywords passed along to PLOTS/POLYFILL depending on
  45. ;           options selected. Note that command line keywords (like
  46. ;           MLINETHICK) will take precedence over options specified with
  47. ;           _EXTRA or their natural names (like THICK).
  48. ; FILL_CONTINENTS -- Set this keyword to 1 to fill continent boundaries with
  49. ;                    a solid color. The color is set by the COLOR keyword.
  50. ;                    Set this keyword to 2 to fill continent boundaries with a
  51. ;                    line fill. For line filling, the COLOR, MLINESTYLE,
  52. ;                    MLINETHICK, ORIENTATION, and SPACING keywords can be used
  53. ;                    to control the type of line fill. Any option valid for
  54. ;                    polyfill can also be used (i.e. PATTERN).
  55. ; HIRES -- Set this keyword to use high-resolution map data instead of the
  56. ;          default low-resolution data. This option is only available if you
  57. ;          have installed the optional high-resolution map datasets. If the
  58. ;          high-resolution data is not available, a warning is printed and
  59. ;          the low-resolution data is used instead.
  60. ;
  61. ;          This keyword can be used in conjunction with the COASTS, COUNTRIES,
  62. ;          FILL_CONTINENTS, and RIVERS keywords.
  63. ;
  64. ; MLINESTYLE -- The line style of the boundaries being drawn.
  65. ;               The default is solid lines.
  66. ; MLINETHICK -- The thickness of the boundary or fill lines.
  67. ;               The default thickness is 1.
  68. ; ORIENTATION -- Set this keyword to the counterclockwise angle in degrees
  69. ;                from horizontal that the line fill should be drawn. The
  70. ;                default is 0. This keyword only has effect if the
  71. ;                FILL_CONTINENTS keyword is set to 2.
  72. ; RIVERS  -- Set this keyword to draw rivers.
  73. ; SPACING -- Set this keyword to the spacing, in centimeters, for a line fill.
  74. ;            This keyword only has effect if the FILL_CONTINENTS keyword is
  75. ;            set to 2. The default is 0.5 centimeters.
  76. ; USA -- Set this keyword to draw borders for each state in the United States
  77. ;        in addition to continental boundaries.
  78. ;
  79. ; OUTPUT KEYWORD PARAMETERS:
  80. ;              NONE
  81. ;
  82. ; OUTPUTS:
  83. ;       Draws continents, etc. over the current map display.
  84. ;
  85. ; COMMON BLOCKS:
  86. ;       None.
  87. ;
  88. ; SIDE EFFECTS:
  89. ;       None.
  90. ;
  91. ; RESTRICTIONS:
  92. ;       See DESCRIPTION.
  93. ;
  94. ; DESCRIPTION:
  95. ;       See PURPOSE.
  96. ;
  97. ; EXAMPLES:
  98. ;
  99. ;         Draw Low-Resolution continents, with high resolution
  100. ;         political boundaries.
  101. ;
  102. ;         MAP_SET
  103. ;         MAP_CONTINENTS
  104. ;         MAP_CONTINENTS,/hires,/countries
  105. ;
  106. ; DEVELOPMENT NOTES:
  107. ;         This version uses !type=3 and uses the NEW (IDL5) map software.
  108. ;         requires map_struct_append in map_set.pro
  109. ;
  110. ; MODIFICATION HISTORY:
  111. ;         SVP, 11/96 ;  Added header template.
  112. ;
  113. ;-
  114. ;
  115. ; ROUTINES:
  116. ;       fun map_getindex,indx   - read the map database index files
  117. ;       fun map_do_segments     - reads and plots map segments
  118. ;       fun map_continents     - the main routine
  119. ; -----------------------------------------------------------------------------
  120.  
  121. FUNCTION map_getindex,indx, error
  122. ;
  123. ; Used to read in the index file for
  124. ; each map data file.  On successful completion, error is set to 0.
  125. ;
  126. openr, lun, indx, /xdr, /get_lun, error = error
  127. if error ne 0 then return, 0        ;File not there or unreadable
  128. segments=0L & readu, lun, segments
  129. dx_map=replicate({ fptr:0L, npts:0L,latmax:0.,latmin:0.,$
  130.                    lonmax:0.,lonmin:0. }, segments )
  131. readu, lun, dx_map & free_lun, lun
  132. free_lun,lun
  133. return, dx_map
  134. END
  135.  
  136.  
  137. PRO map_do_segments, fnames, name, hires, bounds, zvalue, extra, POLYFILL=poly
  138. ; Output a segment file:
  139. ; fnames = [lowresname, hiresname]
  140. ; name = description for error message (boundaries, rivers, etc.
  141. ; hires = 0 for low res, 1 for hires
  142. ; zvalue = Z value for 3D
  143. ; bounds = lat/lon bound.
  144. ; Polyfill = 0 for lines, 1 for polyfill
  145.  
  146. ; Hires = 1 to do hires, 0 for low
  147.  
  148. if n_elements(poly) eq 0 then poly = 0
  149.  
  150. lun = -1
  151. sub = (['low', 'high'])[hires]
  152. fndx = FILEPATH(fnames[hires]+'.ndx', SUBDIR=['resource','maps',sub])
  153. dat =  FILEPATH(fnames[hires]+'.dat', SUBDIR=['resource','maps',sub])
  154. ndx = map_getindex(fndx, error)        ;OPEN it
  155. if error eq 0 then openr, lun, dat,/xdr,/stream, /get, error = error
  156. if (error ne 0) and hires then begin     ;Try low res as a fallback
  157.     message, 'High Res Map File: '+name+' not found, trying low res.', /INFO
  158.     fndx = FILEPATH(fnames[0]+'.ndx', SUBDIR=['resource','maps','low'])
  159.     dat =  FILEPATH(fnames[0]+'.dat', SUBDIR=['resource','maps','low'])
  160.     ndx = map_getindex(fndx, error)        ;OPEN it
  161.     endif            ;Hires
  162. if lun lt 0 then openr, lun, dat,/xdr,/stream, /get, error = error
  163. if error ne 0 then message, 'Map file:'+fnames[hires]+' not found'
  164.  
  165. ; Output a bunch of segments from a standard format file.
  166. lonmin = bounds[0]
  167. lonmax = bounds[2]
  168. latmin = bounds[1]
  169. latmax = bounds[3]
  170. test_lon = ((lonmax-lonmin) mod 360.) ne 0.0
  171. test_lat = lonmin gt -90. or lonmax lt 90.
  172.  
  173.  
  174. ; Prune segments if bounds are set.
  175. if test_lon and test_lat then begin
  176.     subs = where((ndx.latmin lt latmax) and (ndx.latmax gt latmin) and $
  177.                  ((ndx.lonmin lt lonmax) OR (ndx.lonmax gt lonmin)), count)
  178.     if count ne 0 then ndx = ndx(subs)
  179. endif else if test_lon then begin
  180.     subs = where((ndx.lonmin lt lonmax) OR (ndx.lonmax gt lonmin), count)
  181.     if count ne 0 then ndx = ndx(subs)
  182. endif else if test_lat then begin
  183.     subs = where((ndx.latmin lt latmax) and (ndx.latmax gt latmin), count)
  184.     if count ne 0 then ndx = ndx(subs)
  185. endif else count = n_elements(ndx)
  186.     
  187. ; ************** Draw the segments ***************************
  188. ;
  189. if count gt 0 then for i=0, count-1 do begin
  190.     point_lun, lun, ndx[i].fptr
  191.     if ndx[i].npts ge 2 then begin
  192.     xy=fltarr(2,ndx[i].npts, /NOZERO)
  193.     readu,lun,xy
  194.     if keyword_set(poly) then $
  195.       POLYFILL, xy[1,*], xy[0,*], zvalue, NOCLIP=0, /DATA, _EXTRA=extra $
  196.     else PLOTS, xy[1,*], xy[0,*], zvalue, NOCLIP=0, /DATA, _EXTRA=extra
  197.     endif
  198.     endfor
  199.  
  200. FREE_LUN, lun
  201.  
  202. end
  203.  
  204.  
  205.  
  206.  
  207. PRO Map_Continents, $
  208.  USA = kusa, CONTINENTS = kcont, COUNTRIES=kcountries, $
  209.  HIRES=khires, FILL_CONTINENTS=kfill_continents, COASTS=kcoasts, $
  210.  LIMITS = lim_u, MLINESTYLE = mlinestyle, MLINETHICK = mlinethick, $
  211.  SPACING=spacing, COLOR=color, T3D=T3D, ORIENTATION=orientation, $
  212.  ZVALUE=zvalue, RIVERS=krivers, $
  213.  _EXTRA=extra
  214. ;
  215. ;
  216. ;       if fill_continents =1 you get solid polygons
  217. ;       if fill_continents =2 you get lines
  218. ;
  219.  
  220. if !x.type NE 3 THEN message,'Map transform not established.'
  221.  
  222. ;             Map_continents keyword defaults: 
  223. cont = keyword_set(kcont)
  224. usa = keyword_set(kusa)
  225. rivers = keyword_set(krivers)
  226. coasts = keyword_set(kcoasts)
  227. countries = keyword_set(kcountries)
  228. hires = keyword_set(khires)
  229.  
  230. if n_elements(kfill_continents) then fill_continents=kfill_continents $
  231.   else fill_continents = 0
  232.  
  233. if (usa+countries+coasts+rivers eq 0) and n_elements(kcont) eq 0 then cont = 1
  234. if n_elements(zvalue) eq 0 then zvalue = 0.
  235.  
  236. if n_elements(lim_u) eq 4 then l = lim_u $
  237. else if !map.ll_box(0) ne !map.ll_box(2) or $
  238.   !map.ll_box(1) ne !map.ll_box(3) then l = !map.ll_box $
  239. else l = [-90., -360., 90., 360.]
  240.  
  241. latmin = l(0) & lonmin = l(1)
  242. latmax = l(2) & lonmax = l(3)
  243.  
  244.  ;WHY do we have so many ways of expressing a rectangle??
  245. bounds = [lonmin, latmin, lonmax, latmax]
  246.  
  247. ;
  248. ; Process the _EXTRA for graphics keywords. Normally the _EXTRA
  249. ; values overwrite the input values, but not for maps.
  250. ;
  251. if n_elements(mlinestyle) then $
  252.     map_struct_append, extra, 'LINESTYLE', mlinestyle
  253. if n_elements(mlinethick) then $
  254.    map_struct_append, extra, 'THICK', mlinethick
  255. if n_elements(spacing) and (fill_continents eq 2) then $
  256.    map_struct_append, extra, 'SPACING', spacing
  257. if n_elements(color) then $
  258.    map_struct_append, extra, 'COLOR',color
  259. if n_elements(orientation) and (fill_continents eq 2)then $
  260.    map_struct_append, extra, 'ORIENTATION', orientation
  261. if n_elements(t3d) then map_struct_append, extra,'t3d',t3d
  262. ;    Process line-filled continents:
  263. if fill_continents eq 2 then map_struct_append, extra, 'LINE_FILL', 1
  264.  
  265. ; if n_tags(extra) gt 0 then help, /st, extra  ;Debugging
  266.  
  267. ij = 0            ;Default = continents only
  268.  
  269. if rivers ne 0 then begin    ;Rivers
  270.    map_do_segments, ['rlow', 'rhigh'], 'Rivers', hires, bounds, zvalue, extra
  271. endif                ;Rivers
  272.  
  273. if countries ne 0 then begin    ;*** Countries ****
  274.    map_do_segments, ['blow', 'bhigh'], 'Boundaries', hires, bounds, $
  275.     zvalue, extra
  276. endif                ;countries
  277.  
  278. if coasts ne 0 then begin
  279.    map_do_segments, ['clow', 'chigh'], 'Coasts', hires, bounds, zvalue, extra
  280. endif                ;Coasts
  281.  
  282.  
  283. if cont ne 0 or fill_continents ne 0 then begin
  284.    map_do_segments, ['plow', 'phigh'], 'Continents', $
  285.     hires, bounds, zvalue, extra, POLYFILL=fill_continents ne 0
  286. endif                ;continents
  287.  
  288. if usa ne 0 then begin        ;States in USA, a different file
  289.   if cont then ij = 2 else ij = 1
  290.   map_file=FILEPATH('supmap.dat',subdir=['resource','maps'])
  291.   openr, lun, /get, map_file,/xdr,/stream
  292.   npts = 0L
  293.   ;     cont us_only  both
  294.   fbyte = [ 0, 71612L, 165096L]
  295.   nsegs = [ 283, 325, 594 ]
  296.  
  297.   point_lun, lun, fbyte[ij]
  298.  
  299.   for i=1,nsegs[ij] do begin    ;Draw each segment
  300.     READU, lun, npts,maxlat,minlat,maxlon,minlon
  301.     npts = npts / 2        ;# of points
  302.     xy = fltarr(2,npts)
  303.     READU, lun, xy
  304.     if (maxlat lt latmin) or (minlat gt latmax) then goto,skipit
  305.     if ((maxlon lt lonmin) or (minlon gt lonmax)) then BEGIN
  306.             if (lonmax gt 180. and maxlon + 360. ge lonmin) then goto, goon
  307.             goto, skipit
  308.           ENDIF
  309.   goon:    plots,xy[1,*],xy[0,*],zvalue,NOCLIP=0,_EXTRA=extra,/data
  310.   skipit:
  311.   endfor
  312.   FREE_LUN, lun
  313. endif                ;USA
  314.  
  315. end
  316.